package sde.actor.mergesort;
import sde.actor.*;

class Sorter extends Actor{
	private int[] v;
	private int inf, med, sup, contaDone;
	private Sorter parent;
	public static class Sort extends Message{   
		int inf, sup;
		Sorter parent;
		public Sort( Sorter parent, int inf, int sup ){
			this.parent=parent; this.inf=inf; this.sup=sup;
		}
	}//Sort
	private static class Done extends Message{}
	private static final int SORTING=0, MERGING=1;
	public Sorter( int[] v ){
		this.v=v; become( SORTING );
	}
	public void handler( Message m ){
		switch( currentStatus() ){
		case SORTING:
			if( m instanceof Sort ){		
				inf=((Sort)m).inf; 
				sup=((Sort)m).sup;
				parent=((Sort)m).parent;
				if( inf<sup ){
					med=(inf+sup)/2;
					Sorter s1=new Sorter( v );
					s1.send( new Sort( this, inf, med ) );
					Sorter s2=new Sorter( v );
					s2.send( new Sort( this, med+1, sup ) );	
					become( MERGING );
				}
				else
					if( parent!=null ) parent.send( new Done() );
			} break;
		case MERGING:
			if( m instanceof Done ){
				contaDone++;
				if( contaDone==2 ){//do merging
					int aux[]=new int[sup-inf+1];
					int i=inf, j=med+1, k=0;
					while( i<=med && j<=sup ){
						if( v[i]<v[j] ){ aux[k]=v[i]; i++; k++; }
						else{ aux[k]=v[j]; j++; k++; }
					}
					//gestione residui
					while( i<=med ){ aux[k]=v[i]; i++; k++; }
					while( j<=sup ){ aux[k]=v[j]; j++; k++;	}
					//ricopia di aux su v
					for( k=inf; k<=sup; ++k ) v[k]=aux[k-inf];
					if( parent!= null )	parent.send( new Done() );
				}
			}
		}//switch
	}//handler
}//Sorter

public class ActorBasedMergeSort {

	public static void main( String []args ){
		int a[]=new int[40];
		for( int i=0; i<a.length; ++i ) a[i]=a.length-i;
		System.out.println(java.util.Arrays.toString(a));
		ControlMachine cm= new Concurrent();
		new Sorter(a).send( new Sorter.Sort( null, 0, a.length-1) );
		cm.controller(); 
		System.out.println( java.util.Arrays.toString(a) );
	}//main
	
}//ActorMergeSort
